package com.zn.websocket.handler;

import com.zn.websocket.group.ChannelGroups;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URISyntaxException;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * HttpServer 请求处理类
 * @version 0.1
 * @time 12/19/17
 * @since 0.1
 */
public class HttpServerHandler extends ChannelInboundHandlerAdapter {
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpServerHandler.class);
    WebSocketServerHandshaker handshake;
    //调试开启
    static boolean debug = true;

    private final WebSocketHandler webSocketHandler;
    public HttpServerHandler(WebSocketHandler webSocketHandler) {
        this.webSocketHandler = webSocketHandler;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        super.channelRead(ctx, msg);

        if (msg instanceof HttpRequest) {
            HttpRequest httpRequest = (HttpRequest) msg;
            HttpHeaders headers = httpRequest.headers();
            Properties prop = System.getProperties();
//            String os = prop.getProperty("os.name");
//            os.startsWith("Windows")
            if(debug){
                List<Map.Entry<String,String>> ls = headers.entries();
                for(Map.Entry<String,String> i: ls){
                    LOGGER.warn("header  " + i.getKey() + ":" + i.getValue());
                }
            }
            if ("Upgrade".equalsIgnoreCase(headers.get("Connection")) &&
                    "WebSocket".equalsIgnoreCase(headers.get("Upgrade"))) {
                // 替换管道中的 httpHandler 作为WebSocket连接
                ctx.pipeline().replace(this, "webSocketHandler", webSocketHandler);
                /*ctx.pipeline().addLast("idle", new IdleStateHandler(10, 10, 20));
                ctx.pipeline().addLast("heartbeat", new HeartbeatHandler());*/
                // 增加到全局推送中
                ChannelGroups.add(ctx.channel());
                handleHandshake(ctx, httpRequest);
            }
        } else {
            LOGGER.warn("channelRead------->not webSocket Connection");
        }
    }

    protected void handleHandshake(ChannelHandlerContext ctx, HttpRequest req) throws URISyntaxException {
        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketURL(req),
                null, true);
        handshake = wsFactory.newHandshaker(req);
        if (handshake == null) {
            WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
        } else {
            handshake.handshake(ctx.channel(), req);
        }
    }

    protected String getWebSocketURL(HttpRequest req) {
        return "ws://" + req.headers().get("Host") + req.getUri() ;
    }

}
